import SOAPClient from './soapclient'
import { Base64 } from 'js-base64'
import { post } from '@/util/http'
import UkeySeal from './ukey-seal'
/**
 * 容器名称
 */
const Container = {
  user: '9160a3d4-137c-4523-9f02-b9f140a153d7', // 用户证书容器
  ca: '06D5EEFD-52B3-4F65-99AB-AE683FEDD624', // ca证书容器
  root: '06D5EEFD-52B3-4F65-99AB-AE683FEDD623' // root证书容器
}

/**
 * 制作用户证书
 * @param {*} serialNumber 用户id
 * @param {*} userName 用户名称
 * @param {*} type ukey类型
 * @param {*} write 是否写入
 */
const makeCert = (
  makeCertUrl,
  serialNumber,
  userName,
  type = 'user',
  write = true
) => {
  // 制作公钥证书
  return new Promise(resolve => {
    let { status, data } = buildPK10(userName, type)
    console.log('nja===>pk10:', data)
    if (!status) {
      console.error('生成公私钥失败', data)
      resolve({ status: false, msg: '生成公私钥失败;' + data })
      return
    }
    // ca签名
    post(makeCertUrl, {
      p10data: data,
      userId: serialNumber,
      userName: userName
    })
      .then(res => {
        console.log('nja===>res:', res)
        let result = { status: true, data: res.data }
        if (write) {
          // 写证书
          let code = writeUkey(res.data)
          if (!code) {
            result.status = false
            result.msg = '写入证书失败'
          }
        }
        resolve(result)
      })
      .catch(e => {
        console.error('生成用户证书失败', e)
        resolve({ status: false, msg: '生成用户证书失败' })
      })
  })
}

/**
 * 生成证书pk10数据
 * @param {*} name
 * @param {*} roleType
 */
const buildPK10 = (name, roleType) => {
  // 生成密钥对
  SOAPClient.reset()
  SOAPClient.putContainer(Container.user)
  let val = SOAPClient.genKeyPair(2048)
  if (val * 1 === 1) {
    if (roleType !== null) {
      SOAPClient.addEntry('GN', SOAPClient.encode(roleType))
    }
    if (name !== null) {
      SOAPClient.addEntry('CN', SOAPClient.encode(name))
    }
    let valSign = SOAPClient.sign()
    if (valSign.length > 0) {
      return { status: true, data: valSign }
    }
  }
  let valStr = SOAPClient.getStatusString()
  let status = SOAPClient.getStatusCode()
  console.error('buildPK10 result:', valStr, status)
  if (status === '8006') {
    return { status: false, data: '使用ukey错误' }
  }
  if (status === '8007') {
    return { status: false, data: '输入密码错误' }
  }
  SOAPClient.reset()
  return { status: false, data: valStr }
}

/**
 * 写ukey证书
 */
const writeUkey = ({ userCert, caCert, rootCert }) => {
  let result = false
  // 根证书
  if (rootCert) {
    SOAPClient.putContainer(Container.root)
    result = SOAPClient.putCert(rootCert)
    if (result !== '0') {
      console.error('写ROOT证书失败', result)
      return false
    }
  }
  // 写ukey
  if (userCert) {
    SOAPClient.putContainer(Container.user)
    result = SOAPClient.putCert(userCert)
    if (result !== '0') {
      console.error('写用户证书失败', result)
      return false
    }
  }
  // ca证书
  if (caCert) {
    SOAPClient.putContainer(Container.ca)
    result = SOAPClient.putCert(caCert)
    if (result !== '0') {
      console.error('写CA证书失败', result)
      return false
    }
  }

  return true
}

/**
 * 读ukey证书
 * @param {*} caName ca证书名称
 */
const readUkey = (caName = 'CA证书') => {
  return SOAPClient.GetCert(caName)
}

/**
 * 解析ukey证书
 * @param {*} url 解析证书接口地址
 * @param {*} cert 证书内容
 */
const decodeCert = (url, cert = false) => {
  // 读ukey
  return new Promise(resolve => {
    // 请求后台解析证书内容
    if (!cert) {
      cert = readUkey()
    }
    post(url, {
      cert: cert
    })
      .then(res => {
        if (res && res.data) {
          resolve(res.data)
        } else {
          resolve(false)
        }
      })
      .catch(() => {
        resolve(false)
      })
  })
}

/**
 * 数据签名
 * @param {*} src 需要签名的数据
 * @param {*} isBase64 原数据是否是base64格式
 */
const signData = (src, isBase64 = false) => {
  if (!isBase64) {
    src = Base64.encode(src)
  }
  let signData = SOAPClient.SignData(src)
  let signResult = ''
  if (signData !== null && signData.split(',').length > 1) {
    signResult = signData.split(',')[1]
  }
  return signResult
}

/**
 * ukey签章
 * 注意：pdf文档高宽842*595
 * @param baseurl 签章服务地址
 * @param id 文档id
 * @param seals 签章位置参数：[{page:1, x, y}] page签章页，x离左距离，y离下距离（注意是不上）
 * @param paging 骑缝章位置： {y:0}  骑缝章只可以调整与底部距离
 */
const ukeySeal = async ({ baseurl, id, seals, paging }) => {
  if (!id) {
    return Promise.reject(new Error('文档编号{id}为空'))
  }
  if (!(seals && seals.length > 0)) {
    return Promise.reject(new Error('签章位置{seals}不能为空'))
  }
  console.log('test-ukeyseal:1->', baseurl, id, seals, paging)
  let ukey = new UkeySeal(baseurl, id)
  console.log('test-ukeyseal:2->')
  return ukey.seal(seals, paging)
}

// 对外暴露接口
export { makeCert, buildPK10, writeUkey, readUkey, decodeCert, signData, ukeySeal }
